/**
 * 将树级转化为层级
 * @param data 
 * @param fields 要替换的字段
 * @returns 
 */
export const transformToList = (data: any[], fields = { keyField: 'key', titleField: 'title', childrenField: 'children' }) => {
    const { keyField, titleField, childrenField } = fields;
    const dataList: any[] = [];
    const generateList = (data: any[]) => {
        for (let i = 0; i < data.length; i++) {
            const node = data[i];
            dataList.push({ ...node, [keyField]: node[keyField], [titleField]: node[titleField], hasChildren: !!node[childrenField] });
            if (node[childrenField]) {
                generateList(node[childrenField]);
            }
        }
    };
    generateList(data);
    return dataList;
};

/**
 * 获取父亲节点的key
 * @param data 
 * @param fields 要替换的字段
 * @returns 
 */
export const getParentKey = (key, tree, fields = { keyField: 'key', childrenField: 'children' }) => {
    const { keyField, childrenField } = fields;
    let parentKey = null;
    for (let i = 0; i < tree.length; i++) {
        const node = tree[i];
        if (node[childrenField]) {
            if (node[childrenField].some((item) => item[keyField] === key)) {
                parentKey = node[keyField];
            } else if (getParentKey(key, node[childrenField], fields)) {
                parentKey = getParentKey(key, node[childrenField], fields);
            }
        }
    }
    return parentKey;
};

/**
 * 获取父亲节点信息
 * @param data 
 * @param fields 要替换的字段
 * @returns 
 */
export const getParent = (key, tree, fields = { keyField: 'key', childrenField: 'children' }) => {
    const { keyField, childrenField } = fields;
    let parent = null;
    for (let i = 0; i < tree.length; i++) {
        const node = tree[i];
        if (node[childrenField]) {
            if (node[childrenField].some((item) => item[keyField] === key)) {
                parent = node;
            } else if (getParent(key, node[childrenField], fields)) {
                parent = getParent(key, node[childrenField], fields);
            }
        }
    }
    return parent;
};

/**
 * 将树某一属性平铺到该层级  {node:{a:'',b:''}}=>{node:{},a:'',b:''}
 * @param data 
 * @returns 
 */
export const transformDataByFlatProperty = (data, fields = { keyField: 'node', childrenField: 'subNodes' }) => {
    const { keyField, childrenField } = fields;
    data.forEach((item, index) => {
        data[index] = {
            ...data[index],
            ...data[index][keyField]
        };
        if (item[childrenField] && item[childrenField].length) {
            data[index][childrenField] = transformDataByFlatProperty(item[childrenField], fields);
        }
    });
    return data;
};


/**
 * 获取选中该节点的完整路径信息
 * @param data 
 * @returns 
 */
export const treeFilter = (tree: any[], func: Function) => {
    // 使用map复制一下节点，避免修改到原树
    return tree
        .map((node) => ({ ...node }))
        .filter((node: any) => {
            node.subNodes = node.subNodes && treeFilter(node.subNodes, func);
            return func(node) || (node.subNodes && node.subNodes.length);
        });
};

/**
 * 获取选中该节点的完整路径id
 * @param data 
 * @returns 
 */
export const getMenuId = (obj: any, path: any = []) => {
    path.push(obj.catalogCode);
    if (obj.subNodes && obj.subNodes.length) {
        getMenuId(obj.subNodes[0], path);
    }
    return path;
};

// 获取所有子节点
export const getChildNodes = (node, fields = { keyField: 'node', childrenField: 'subNodes' }) => {
    if (!node[fields.childrenField]) {
        return [];
    }
    let childNodes: any = [];
    node[fields.childrenField].forEach((child) => {
        childNodes.push(child);
        const grandchildren = getChildNodes(child);
        childNodes = childNodes.concat(grandchildren);
    });
    return childNodes;
};

// 获取某个子节点，其功能是在一个树状结构的数据中查找具有特定ID的节点
export const findNodeById = (node, targetId, fields = { keyField: 'catalogCode', childrenField: 'subNodes' }) => {
    if (node[fields.keyField] === targetId) {
        return node;
    } else if (node[fields.childrenField] && node[fields.childrenField].length > 0) {
        for (let i = 0; i < node[fields.childrenField].length; i++) {
            const foundNode = findNodeById(node[fields.childrenField][i], targetId, fields);//最终得到指定node或为null
            if (foundNode) {//如果不为null则可返回此节点
                return foundNode;
            }
        }
    }
    return null;
};